#include <iostream>
#include "EigenePhysik.h"
#include "graphics.h"
#include "include.h"
#include "server.h"
#include "client.h"

#define CLIENT 1

using namespace std;

int main(){
    // Spieleinstellungen treffen:
    int kugelanzahl = 20;
    int kugelradius = 10;
    int lochradius = 2.0*kugelradius;
    int rpb = 2; //Rechenschritte pro Bild
    int kugelNr = -1;
    int gewinner = -1;
    int port;

#if CLIENT
    string ip;

    cout << "Server IP: ";
    cin >> ip;
    cout << endl << "Port: ";
    cin >> port;

    Client client;
    client.startClient(ip, port);
    client.connectToServer(3);
    networkMessage* message;
    bool loop = false;

    while(!loop){
        loop = client.waitForStart();
    }

    //zum offline Testen diese Zeile auskommentieren und in der include.h NETWORKTEST auf 1 setzen
    kugelanzahl = client.getKugelAnzahl();
    kugelNr = client.getKugelNr();
    cout << "Eigene Kugel: " << kugelNr << endl;
    cout << "Kugel Anzahl: " << kugelanzahl << endl;

    GLfloat colorContainer[] = {
        0.9f, 0.0f, 0.0f,
        0.0f, 0.9f, 0.0f,
        0.0f, 0.0f, 0.9f,
        0.9f, 0.9f, 0.9f,
        0.0f, 0.0f, 0.0f
    };
    cout << " Erstelle EigenePhysik ... " << endl;
    EigenePhysik eigenePhysik = EigenePhysik(kugelanzahl, kugelradius, 0.0f, 904.0f, 648.0f, 0.0f, lochradius);
    cout << " Erstelle Graphics ... " << endl;
    graphics graphic;
    cout << " Oeffne Fenster ... " << endl;
    graphic.open(1280,800);
    cout << " Erstelle Feldanzeige ... " << endl;
    graphic.loadShaders();
    graphic.init();
    graphic.field();
    cout << " Setze Kugeln in Bewegung ... " << endl;
    // Alle Kugeln in Bewegung setzen
    for(int i=0; i<kugelanzahl; i++){
        eigenePhysik.SetzeKugelInBewegung(i, cos((double)i), sin((double)i));
    }

    while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
		glfwGetWindowParam( GLFW_OPENED ) && loop){

        for(int i=0; i < rpb; i++){
            eigenePhysik.berechneNaechstesBild();
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        graphic.field();

        for(int i = 0; i < kugelanzahl; i++){
            graphic.bowl(eigenePhysik.holeXPosVonKugel(i), eigenePhysik.holeYPosVonKugel(i), kugelradius, colorContainer[i*3 + 0], colorContainer[i*3 + 1], colorContainer[i*3 + 2]);

        }
        glfwSwapBuffers();
        //graphic.bowl(eigenePhysik.holeXPosVonKugel(i), eigenePhysik.holeYPosVonKugel(i), 0.9f, 0.0f, 0.0f);
        //graphic.bowl(eigenePhysik.holeXPosVonKugel(i), eigenePhysik.holeYPosVonKugel(i), 0.0f, 0.9f, 0.0f);
        //graphic.bowl(eigenePhysik.holeXPosVonKugel(i), eigenePhysik.holeYPosVonKugel(i), 0.0f, 0.0f, 0.9f);
        //graphic.bowl(eigenePhysik.holeXPosVonKugel(i), eigenePhysik.holeYPosVonKugel(i), 0.9f, 0.9f, 0.9f);
        //graphic.bowl(eigenePhysik.holeXPosVonKugel(i), eigenePhysik.holeYPosVonKugel(i), 0.0f, 0.0f, 0.0f);

        //graphic.bowl(i,0.0f,0.5f,0.7f,0.2f);

        //glfwSleep(0.001);

        if(client.messageReceived()){
            message = client.getMessage();
            if(message->type == 5) //STOP
            {
                cout << "Spiel zu Ende" << endl;
                if(message->value != -1){
                    if(message->value == kugelNr){
                        cout << endl << "Spiel gewonnen" << endl << endl;
                    }else{
                        cout << endl << "Spieler " << message->value << " hat das Spiel gewonnen" << endl << endl;
                    }
                }
                loop = false;
            }
            if(message->type == 8) //CONNECTION_LOST
            {
                eigenePhysik.setzeKugelInaktiv(message->value);
                if(kugelNr == message->value){
                    cout << "Verbindung zum Server verloren" << endl;
                    loop = false;
                }else{
                    cout << "Spieler " << message->value << " hat die Verbindung zum Server verloren" << endl;
                }
            }
            if(message->type == 9) //UPDATE
            {
                for(int i = 0; i < kugelanzahl; i++){
                   eigenePhysik.setzeKugel(i, message->data[i][0], message->data[i][1], message->data[i][2], message->data[i][3], message->data[i][4]);
                }
            }
        }
    }

    graphic.close();

    client.stopClient();

    cout << " Bye, bye " << endl;

#else
    cout << "number of players: ";
    cin >> kugelanzahl;
    cout << "port: ";
    cin >> port;
    Server server;
    server.setPhysik(kugelanzahl, kugelradius, lochradius, rpb);
    server.startServer(port, 3);
    server.waitForClients();
    server.startGame();
    server.stopGame();
    server.stopServer();
#endif

    return 0;
}

